﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Tsanie.ShellExtension;
using Tsanie.Properties;
using System.Drawing;
using System.Threading;
using Microsoft.Win32;
using System.IO;

namespace Tsanie {
    [ComVisible(true)]
    [Guid("C6E7702D-987A-4847-8994-8CBB077F7587")]
    [ExtensionFileTypes(".txt,.log", FindAssoc = true)]
    public class TextThumbnailContextMenu : ContextMenuHandlerBase {
        private string _text;
        private string _helpText;
        private Bitmap _icon;
        private EventHandler _handler;

        public TextThumbnailContextMenu()
            : base() {
            _text = Resource.MenuText;
            _helpText = Resource.MenuHelpText;
            _icon = Resource.MenuIcon;
            _handler = new EventHandler(Menu_Click);
        }
        public override void OnMenuCreate() {
            MenuItem item = new MenuItem(_text, _helpText, _icon, _handler);
            this.MenuItems.Add(item);
        }
        private void Menu_Click(object sender, EventArgs e) {
            ConfigForm.Form.Show();
            ConfigForm.Form.Focus();
        }
    }

    [ComVisible(true)]
    [Guid("CAA330E5-556A-4e5f-AA71-D6108386207E")]
    [ExtensionFileTypes(".txt,.log", FindAssoc = false)]
    public class TextThumbnail : ThumbnailHandlerBase {
        private static readonly Bitmap textBackground;
        private static readonly Bitmap logBackground;
        private static readonly Brush brush;
        private static readonly RectangleF rectangle;
        private static readonly StringFormat fmt;
        private static Font font;
        private static int count;

        static TextThumbnail() {
            textBackground = Resource.textBackground;
            logBackground = Resource.logBackground;
            brush = new SolidBrush(Color.Black);
            rectangle = new RectangleF(6, 5, 206, 248);
            fmt = new StringFormat();
            fmt.Trimming = StringTrimming.EllipsisCharacter;
            fmt.FormatFlags = StringFormatFlags.LineLimit;
            TextThumbnail.Font = GetSavedFont();
        }
        public static Font GetSavedFont() {
            Font font;
            RegistryKey root = Registry.CurrentUser.OpenSubKey(@"Software\Tsanie\TextThumbnail");
            if (root == null) {
                // 首次，注册键值
                root = Registry.CurrentUser.CreateSubKey(@"Software\Tsanie\TextThumbnail");
                font = new Font("Segoe UI", 20.2f);
                root.SetValue("FontFamily", font.Name, RegistryValueKind.String);
                root.SetValue("FontSize", (int)(font.Size * 10), RegistryValueKind.DWord);
            } else {
                font = new Font(root.GetValue("FontFamily", "Segoe UI") as string,
                    (int)root.GetValue("FontSize", 202) / 10.0f);
            }
            root.Close();
            return font;
        }

        public static Font Font {
            get { return font; }
            set {
                font = value;
                Bitmap tmp = new Bitmap(50, 50);
                Graphics g = Graphics.FromImage(tmp);
                SizeF size = g.MeasureString("i", font);
                float width = 206 / size.Width * 2;
                float height = 248 / size.Height;
                count = (int)(width * height) + 6;
                g.Dispose(); g = null;
                tmp.Dispose(); tmp = null;
#if TRACE
                Common.OutputDebugString("set_Font(Font):: count: {0:0.00} x {1:0.00} ~= {2}", width, height, count);
#endif
            }
        }
        protected override Bitmap GetImage {
            get {
                string str = string.Empty;
                FileStream stream = new FileStream(this.Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                byte[] bs = new byte[count * 2];
                int c = stream.Read(bs, 0, bs.Length);
                stream.Close();
                stream = null;
                bool flag = true;
                if (c > 3) {
                    if (bs[0] == 0xef && bs[1] == 0xbb && bs[2] == 0xbf) {  // UTF-8
                        str = Encoding.UTF8.GetString(bs);
                        flag = false;
                    }
                } else if (c > 2) {
                    if (bs[0] == 0xfe && bs[1] == 0xff) {   // Unicode Big-Endian
                        str = Encoding.BigEndianUnicode.GetString(bs);
                        flag = false;
                    } else if (bs[0] == 0xff && bs[1] == 0xfe) {    // Unicode Little-Endian
                        str = Encoding.Unicode.GetString(bs);
                        flag = false;
                    }
                }
                if (flag) {
                    str = Encoding.Default.GetString(bs);
                }
#if DEBUG
                Common.OutputDebugString("get_GetImage(void):: text - '{0}'", str);
#endif
                return GetThumbnail(font, str, this.Filename.Substring(this.Filename.LastIndexOf('.') + 1));
            }
        }

        public static Bitmap GetThumbnail(Font font, string text, string ext) {
            Bitmap bmp = new Bitmap(ext == "log" ? logBackground : textBackground);
            Graphics g = Graphics.FromImage(bmp);
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            g.DrawString(text, font, brush, rectangle, fmt);
            return bmp;
        }
    }

}
